package com.lifeverse.entity;

import jakarta.persistence.*;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 网络健康指标实体类
 * 记录网络的健康状态和各项指标
 */
@Data
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "network_health_metrics", indexes = {
    @Index(name = "idx_metrics_timestamp", columnList = "measurement_time"),
    @Index(name = "idx_metrics_health_score", columnList = "overall_health_score"),
    @Index(name = "idx_metrics_network_type", columnList = "network_type")
})
public class NetworkHealthMetrics extends BaseEntity {
    
    /**
     * 网络类型枚举
     */
    public enum NetworkType {
        GLOBAL("全局网络", "整个生命体网络"),
        REGIONAL("区域网络", "特定区域的生命体网络"),
        TYPE_BASED("类型网络", "基于生命体类型的网络"),
        GROUP_BASED("群体网络", "基于群体的网络"),
        RELATIONSHIP_BASED("关系网络", "基于特定关系类型的网络");
        
        private final String displayName;
        private final String description;
        
        NetworkType(String displayName, String description) {
            this.displayName = displayName;
            this.description = description;
        }
        
        public String getDisplayName() {
            return displayName;
        }
        
        public String getDescription() {
            return description;
        }
    }
    
    /**
     * 健康状态枚举
     */
    public enum HealthStatus {
        EXCELLENT("优秀", 90, 100),
        GOOD("良好", 70, 89),
        FAIR("一般", 50, 69),
        POOR("较差", 30, 49),
        CRITICAL("危险", 0, 29);
        
        private final String displayName;
        private final int minScore;
        private final int maxScore;
        
        HealthStatus(String displayName, int minScore, int maxScore) {
            this.displayName = displayName;
            this.minScore = minScore;
            this.maxScore = maxScore;
        }
        
        public String getDisplayName() {
            return displayName;
        }
        
        public int getMinScore() {
            return minScore;
        }
        
        public int getMaxScore() {
            return maxScore;
        }
        
        public static HealthStatus fromScore(BigDecimal score) {
            int scoreInt = score.intValue();
            for (HealthStatus status : values()) {
                if (scoreInt >= status.minScore && scoreInt <= status.maxScore) {
                    return status;
                }
            }
            return CRITICAL;
        }
    }
    
    /**
     * 网络类型
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "network_type", nullable = false, length = 20)
    private NetworkType networkType;
    
    /**
     * 网络标识符（可选，用于特定网络）
     */
    @Column(name = "network_identifier", length = 100)
    private String networkIdentifier;
    
    /**
     * 测量时间
     */
    @Column(name = "measurement_time", nullable = false)
    private LocalDateTime measurementTime;
    
    /**
     * 总体健康评分（0-100）
     */
    @Column(name = "overall_health_score", nullable = false, precision = 5, scale = 2)
    private BigDecimal overallHealthScore;
    
    /**
     * 健康状态
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "health_status", nullable = false, length = 20)
    private HealthStatus healthStatus;
    
    /**
     * 网络节点数量
     */
    @Column(name = "total_nodes", nullable = false)
    private Integer totalNodes;
    
    /**
     * 活跃节点数量
     */
    @Column(name = "active_nodes", nullable = false)
    private Integer activeNodes;
    
    /**
     * 网络边数量
     */
    @Column(name = "total_edges", nullable = false)
    private Integer totalEdges;
    
    /**
     * 活跃边数量
     */
    @Column(name = "active_edges", nullable = false)
    private Integer activeEdges;
    
    /**
     * 网络密度（0-1）
     */
    @Column(name = "network_density", nullable = false, precision = 8, scale = 6)
    private BigDecimal networkDensity;
    
    /**
     * 平均度数
     */
    @Column(name = "average_degree", nullable = false, precision = 8, scale = 4)
    private BigDecimal averageDegree;
    
    /**
     * 聚类系数（0-1）
     */
    @Column(name = "clustering_coefficient", nullable = false, precision = 8, scale = 6)
    private BigDecimal clusteringCoefficient;
    
    /**
     * 连通性评分（0-100）
     */
    @Column(name = "connectivity_score", nullable = false, precision = 5, scale = 2)
    private BigDecimal connectivityScore;
    
    /**
     * 稳定性评分（0-100）
     */
    @Column(name = "stability_score", nullable = false, precision = 5, scale = 2)
    private BigDecimal stabilityScore;
    
    /**
     * 活跃度评分（0-100）
     */
    @Column(name = "activity_score", nullable = false, precision = 5, scale = 2)
    private BigDecimal activityScore;
    
    /**
     * 多样性评分（0-100）
     */
    @Column(name = "diversity_score", nullable = false, precision = 5, scale = 2)
    private BigDecimal diversityScore;
    
    /**
     * 效率评分（0-100）
     */
    @Column(name = "efficiency_score", nullable = false, precision = 5, scale = 2)
    private BigDecimal efficiencyScore;
    
    /**
     * 鲁棒性评分（0-100）
     */
    @Column(name = "robustness_score", nullable = false, precision = 5, scale = 2)
    private BigDecimal robustnessScore;
    
    /**
     * 创新能力评分（0-100）
     */
    @Column(name = "innovation_score", nullable = false, precision = 5, scale = 2)
    private BigDecimal innovationScore;
    
    /**
     * 学习能力评分（0-100）
     */
    @Column(name = "learning_score", nullable = false, precision = 5, scale = 2)
    private BigDecimal learningScore;
    
    /**
     * 适应能力评分（0-100）
     */
    @Column(name = "adaptability_score", nullable = false, precision = 5, scale = 2)
    private BigDecimal adaptabilityScore;
    
    /**
     * 协作能力评分（0-100）
     */
    @Column(name = "collaboration_score", nullable = false, precision = 5, scale = 2)
    private BigDecimal collaborationScore;
    
    /**
     * 信任度评分（0-100）
     */
    @Column(name = "trust_score", nullable = false, precision = 5, scale = 2)
    private BigDecimal trustScore;
    
    /**
     * 响应时间（毫秒）
     */
    @Column(name = "response_time_ms", nullable = false)
    private Long responseTimeMs;
    
    /**
     * 吞吐量（每秒处理数量）
     */
    @Column(name = "throughput_per_second", nullable = false, precision = 10, scale = 2)
    private BigDecimal throughputPerSecond;
    
    /**
     * 错误率（0-100）
     */
    @Column(name = "error_rate", nullable = false, precision = 5, scale = 2)
    private BigDecimal errorRate;
    
    /**
     * 可用性（0-100）
     */
    @Column(name = "availability", nullable = false, precision = 5, scale = 2)
    private BigDecimal availability;
    
    /**
     * 负载水平（0-100）
     */
    @Column(name = "load_level", nullable = false, precision = 5, scale = 2)
    private BigDecimal loadLevel;
    
    /**
     * 资源利用率（0-100）
     */
    @Column(name = "resource_utilization", nullable = false, precision = 5, scale = 2)
    private BigDecimal resourceUtilization;
    
    /**
     * 异常检测评分（0-100，越高表示越正常）
     */
    @Column(name = "anomaly_score", nullable = false, precision = 5, scale = 2)
    private BigDecimal anomalyScore;
    
    /**
     * 预警级别（0-5）
     */
    @Column(name = "alert_level", nullable = false)
    private Integer alertLevel;
    
    /**
     * 趋势指标（JSON格式）
     */
    @Column(name = "trend_indicators", columnDefinition = "TEXT")
    private String trendIndicators;
    
    /**
     * 详细指标（JSON格式）
     */
    @Column(name = "detailed_metrics", columnDefinition = "TEXT")
    private String detailedMetrics;
    
    /**
     * 异常事件（JSON格式）
     */
    @Column(name = "anomaly_events", columnDefinition = "TEXT")
    private String anomalyEvents;
    
    /**
     * 性能基准（JSON格式）
     */
    @Column(name = "performance_benchmarks", columnDefinition = "TEXT")
    private String performanceBenchmarks;
    
    /**
     * 建议措施（JSON格式）
     */
    @Column(name = "recommendations", columnDefinition = "TEXT")
    private String recommendations;
    
    /**
     * 备注信息
     */
    @Column(name = "notes", length = 500)
    private String notes;
    
    @PrePersist
    protected void onCreate() {
        super.onCreate();
        if (measurementTime == null) {
            measurementTime = LocalDateTime.now();
        }
        updateHealthStatus();
    }
    
    @PreUpdate
    protected void onUpdate() {
        super.onUpdate();
        updateHealthStatus();
    }
    
    /**
     * 更新健康状态
     */
    public void updateHealthStatus() {
        this.healthStatus = HealthStatus.fromScore(this.overallHealthScore);
    }
    
    /**
     * 计算总体健康评分
     */
    public void calculateOverallHealthScore() {
        // 权重分配
        BigDecimal connectivityWeight = BigDecimal.valueOf(0.15);
        BigDecimal stabilityWeight = BigDecimal.valueOf(0.15);
        BigDecimal activityWeight = BigDecimal.valueOf(0.10);
        BigDecimal diversityWeight = BigDecimal.valueOf(0.10);
        BigDecimal efficiencyWeight = BigDecimal.valueOf(0.10);
        BigDecimal robustnessWeight = BigDecimal.valueOf(0.10);
        BigDecimal innovationWeight = BigDecimal.valueOf(0.08);
        BigDecimal learningWeight = BigDecimal.valueOf(0.08);
        BigDecimal adaptabilityWeight = BigDecimal.valueOf(0.07);
        BigDecimal collaborationWeight = BigDecimal.valueOf(0.07);
        
        this.overallHealthScore = connectivityScore.multiply(connectivityWeight)
                .add(stabilityScore.multiply(stabilityWeight))
                .add(activityScore.multiply(activityWeight))
                .add(diversityScore.multiply(diversityWeight))
                .add(efficiencyScore.multiply(efficiencyWeight))
                .add(robustnessScore.multiply(robustnessWeight))
                .add(innovationScore.multiply(innovationWeight))
                .add(learningScore.multiply(learningWeight))
                .add(adaptabilityScore.multiply(adaptabilityWeight))
                .add(collaborationScore.multiply(collaborationWeight))
                .setScale(2, java.math.RoundingMode.HALF_UP);
        
        updateHealthStatus();
    }
    
    /**
     * 判断网络是否健康
     */
    public boolean isHealthy() {
        return overallHealthScore.compareTo(BigDecimal.valueOf(70)) >= 0;
    }
    
    /**
     * 判断网络是否稳定
     */
    public boolean isStable() {
        return stabilityScore.compareTo(BigDecimal.valueOf(70)) >= 0;
    }
    
    /**
     * 判断网络是否高效
     */
    public boolean isEfficient() {
        return efficiencyScore.compareTo(BigDecimal.valueOf(70)) >= 0;
    }
    
    /**
     * 判断网络是否活跃
     */
    public boolean isActive() {
        return activityScore.compareTo(BigDecimal.valueOf(60)) >= 0;
    }
    
    /**
     * 判断是否需要预警
     */
    public boolean needsAlert() {
        return alertLevel >= 3 || overallHealthScore.compareTo(BigDecimal.valueOf(50)) < 0;
    }
    
    /**
     * 判断是否有异常
     */
    public boolean hasAnomalies() {
        return anomalyScore.compareTo(BigDecimal.valueOf(70)) < 0;
    }
    
    /**
     * 获取节点活跃率
     */
    public BigDecimal getNodeActivityRate() {
        if (totalNodes == 0) return BigDecimal.ZERO;
        return BigDecimal.valueOf(activeNodes)
                .divide(BigDecimal.valueOf(totalNodes), 4, java.math.RoundingMode.HALF_UP)
                .multiply(BigDecimal.valueOf(100));
    }
    
    /**
     * 获取边活跃率
     */
    public BigDecimal getEdgeActivityRate() {
        if (totalEdges == 0) return BigDecimal.ZERO;
        return BigDecimal.valueOf(activeEdges)
                .divide(BigDecimal.valueOf(totalEdges), 4, java.math.RoundingMode.HALF_UP)
                .multiply(BigDecimal.valueOf(100));
    }
    
    /**
     * 获取网络规模等级
     */
    public String getNetworkSizeCategory() {
        if (totalNodes < 10) return "微型";
        if (totalNodes < 50) return "小型";
        if (totalNodes < 200) return "中型";
        if (totalNodes < 1000) return "大型";
        return "超大型";
    }
    
    /**
     * 获取性能等级
     */
    public String getPerformanceGrade() {
        BigDecimal performanceScore = efficiencyScore
                .add(BigDecimal.valueOf(100).subtract(BigDecimal.valueOf(responseTimeMs / 10.0)))
                .add(throughputPerSecond.multiply(BigDecimal.valueOf(10)))
                .add(BigDecimal.valueOf(100).subtract(errorRate))
                .add(availability)
                .divide(BigDecimal.valueOf(5), 2, java.math.RoundingMode.HALF_UP);
        
        if (performanceScore.compareTo(BigDecimal.valueOf(90)) >= 0) return "A+";
        if (performanceScore.compareTo(BigDecimal.valueOf(80)) >= 0) return "A";
        if (performanceScore.compareTo(BigDecimal.valueOf(70)) >= 0) return "B";
        if (performanceScore.compareTo(BigDecimal.valueOf(60)) >= 0) return "C";
        return "D";
    }
}